#include "stdafx.h"
#include "TreeListCtrl.h"

#include "resource.h"


BEGIN_MESSAGE_MAP(CTreeListCtrl, CListCtrl)
	//{{AFX_MSG_MAP(CTreeListCtrl)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CTreeListCtrl

CTreeListCtrl::CTreeListCtrl()
{
}

CTreeListCtrl::~CTreeListCtrl()
{
}

/////////////////////////////////////////////////////////////////////////////
// CTreeListCtrl overrides

void CTreeListCtrl::PreSubclassWindow() 
{
	// LVS_EX_GRIDLINES // 5.0: LVS_EX_LABELTIP 
	SetExtendedStyle(LVS_EX_FULLROWSELECT);

	if (NULL == m_ilState.GetSafeHandle())
	{
		m_ilState.Create(IDB_State, 16, 1, RGB(255, 0, 0));
	}
	SetImageList(&m_ilState, LVSIL_STATE);
	
	CListCtrl::PreSubclassWindow();
}

/////////////////////////////////////////////////////////////////////////////
// CTreeListCtrl operations

BOOL CTreeListCtrl::Create
	(
	DWORD			dwStyle,
	const RECT&		rect,
	CWnd*			pParentWnd,
	UINT			nID
	)
{
	if (!CListCtrl::Create(dwStyle, rect, pParentWnd, nID))
		return FALSE;

	// LVS_EX_GRIDLINES // 5.0: LVS_EX_LABELTIP 
	SetExtendedStyle(LVS_EX_FULLROWSELECT);

	if (NULL == m_ilState.GetSafeHandle())
	{
		m_ilState.Create(IDB_State, 16, 1, RGB(255, 0, 0));
	}
	SetImageList(&m_ilState, LVSIL_STATE);

	return TRUE;
}

int CTreeListCtrl::AddItem
	(
	LPCTSTR		lpszItem,
	int			nLevel
	)
{
	LVITEM			item;
	tree_list_info	info;
	int				nItem;
	
	nItem = m_tree.size();
	info.m_nLevel	= nLevel;
	info.m_nImage	= nLevel;
	/*char strnum[10];
	itoa(GetHeaderCtrl()->GetItemCount(),strnum,10);
	CString turn=strnum;
	MessageBox(turn);*/
	info.m_lstCols.resize(GetHeaderCtrl()->GetItemCount());
	info.m_lstCols[0] = lpszItem;
	info.m_bCollapsed = true;
	m_tree.push_back(info);

	item.mask		= LVIF_TEXT | LVIF_IMAGE | LVIF_INDENT | LVIF_STATE | LVIF_PARAM;
	item.iItem		= nItem;
	item.iSubItem	= 0;
	item.pszText	= (LPTSTR)(LPCTSTR)info.m_lstCols[0];
	item.iImage		= info.m_nImage;
	item.iIndent	= info.m_nLevel;
	item.state		= INDEXTOSTATEIMAGEMASK(info.m_bCollapsed ? 1 : 2);
	item.stateMask	= LVIS_STATEIMAGEMASK;
	item.lParam		= nItem;

	if (info.m_nLevel == 0)
	{
		CListCtrl::InsertItem(&item);
	}

	return nItem;
}

BOOL  CTreeListCtrl::SetItemText
	(
	int			nItem,
	int			nSubItem,
	LPCTSTR		lpszText
	)
{
	m_tree.at(nItem).m_lstCols[nSubItem] = lpszText;
	return CListCtrl::SetItemText(nItem, nSubItem, lpszText);
}

/////////////////////////////////////////////////////////////////////////////
// CTreeListCtrl protected functions

int CTreeListCtrl::InsertItem
	(
	int				nItem,
	int				nPosArray,
	tree_list_info&	info
	)
{
	LVITEM			item;

	item.mask		= LVIF_TEXT | LVIF_IMAGE | LVIF_INDENT | LVIF_STATE | LVIF_PARAM;
	item.iItem		= nItem;
	item.iSubItem	= 0;
	item.pszText	= (LPTSTR)(LPCTSTR)info.m_lstCols[0];
	item.iImage		= info.m_nImage;
	item.iIndent	= info.m_nLevel;
	item.state		= INDEXTOSTATEIMAGEMASK(info.m_bCollapsed ? 1 : 2);
	item.stateMask	= LVIS_STATEIMAGEMASK;
	item.lParam		= nPosArray;

	int	nItemRes = CListCtrl::InsertItem(&item);

	for (int i = 1; i < info.m_lstCols.size(); i++)
	{
		CListCtrl::SetItemText(nItemRes, i, info.m_lstCols[i]);
	}
	return nItemRes;
}

BOOL CTreeListCtrl::DeleteAllItems()
{
	m_tree.clear();
	return CListCtrl::DeleteAllItems();
}

void CTreeListCtrl::Collapse
	(
	int		nPos,
	int		nItem
	)
{
	int				nLevel;
	int				nLast;
	LVITEM			item;
	
	tree_list_info&	info = m_tree[nPos];
	info.m_bCollapsed = true;

	SetRedraw(0);
	nLevel	= info.m_nLevel;
	nLast	= GetHeaderCtrl()->GetItemCount();
	item.mask		= LVIF_PARAM;
	item.iSubItem	= 0;

	int nCounter = nItem + 1;
	if (nCounter < nLast)
	{
		do
		{
			item.iItem		= nCounter;
			GetItem(&item);
			if (m_tree[item.lParam].m_nLevel > nLevel)
				DeleteItem(nItem + 1);
		}
		while (m_tree[item.lParam].m_nLevel > nLevel && GetHeaderCtrl()->GetItemCount() > nCounter);
	}

	SetRedraw(1);
}

int CTreeListCtrl::Expand
	(
	int		nItem,
	bool	bRecursive,
	int&	nCounterInsert
	)
{
	tree_list_info&	info	= m_tree[nItem];
	info.m_bCollapsed		= false;

	int				nCounter;
	int				nLevel;
	
	nCounter		= nItem + 1;
	nCounterInsert	= nCounterInsert + 1;
	nLevel			= info.m_nLevel;
	while (nCounter < m_tree.size() && m_tree[nCounter].m_nLevel > nLevel)
	{
		if (m_tree[nCounter].m_nLevel > nLevel)
		{
			if (bRecursive)
			{
				m_tree[nCounter].m_bCollapsed = false;
			}
			InsertItem(nCounterInsert, nCounter, m_tree[nCounter]);
		}

		if (bRecursive || !m_tree[nCounter].m_bCollapsed)
		{
			nCounter = Expand(nCounter, bRecursive, nCounterInsert);
		}
		else
		{
			int	nSonLevel;

			nSonLevel = m_tree[nCounter].m_nLevel;
			while (++nCounter < m_tree.size() && m_tree[nCounter].m_nLevel > nSonLevel)
			{
			}

			nCounterInsert++;
		}		
	}

	
	return nCounter;
}



